home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / du_lib / popup.c < prev    next >
C/C++ Source or Header  |  1995-07-10  |  6KB  |  272 lines

  1. /*
  2.   DU_LIB v2
  3.   Gem Window Management & Dialog Library For Lattice C
  4.   ½1994, by Craig Graham.
  5.   
  6.   Based on the DU_LIBv1 Library for HiSoft Basic.
  7. */
  8.  
  9. /*
  10.   Popup Menu Handler
  11. */
  12.  
  13. #include "dulib.h"
  14. #include <string.h>
  15.  
  16. /*
  17.     Side-pointing arrow (OSF Motif style) for popups
  18. */
  19. MFORM SIDEARRW =
  20. {    0x0001,0x0007,0x0002,0x0000,0x0001,
  21. /* Mask data */
  22.     0x0000,0x0000,0x0600,0x0E00,
  23.     0x1E00,0x3FFC,0x7FF4,0xFFF4,
  24.     0x7FF4,0x3FFC,0x1E00,0x0E00,
  25.     0x0600,0x0000,0x0000,0x0000,
  26. /* Cursor data */
  27.     0x0000,0x0000,0x0000,0x0400,
  28.     0x0C00,0x1C00,0x3FF8,0x7FF8,
  29.     0x3FF8,0x1C00,0x0C00,0x0400,
  30.     0x0000,0x0000,0x0000,0x0000
  31. };
  32.  
  33. /*Form an <n> entry pop-up menu for <object> in <dialog>, and return a selection from it.*/
  34. short form_popup(short dialog,short object, short n, short current, char *t[])
  35. {
  36.     static OBJECT popup[50];
  37.     static TEDINFO texts[30];
  38.     OBJECT* l;
  39.     OBJECT* lt;
  40.     TEDINFO* ltb;
  41.     MFDB scr,obm;
  42.     short p[8];
  43.     short *buf;
  44.     short mb,a,max_w,f;
  45.     GRECT oxywh;
  46.     short rtn;
  47.     short c,e,mx,my,dummy,ex_f,sel_f;
  48.     
  49.     graf_mkstate(&mx,&my,&sel_f,&junk);
  50.     
  51.     if (sel_f) sel_f=TRUE; else sel_f=FALSE;
  52.     
  53.     vs_clip(x_handle, 0, NULL);
  54.     
  55.     rsrc_gaddr(0,dialog,&l);
  56.     objc_xywh(l,object,&oxywh);
  57.  
  58.     if (n==0)
  59.     {
  60.         rtn=0;
  61.     } else {
  62.         popup->ob_next=-1;                    /*Create a popup menu structure*/
  63.         popup->ob_head=1;
  64.         popup->ob_tail=n+1;
  65.         popup->ob_flags=0;
  66.         popup->ob_state=mask_shadowed;
  67.         popup->ob_type=G_BOX;
  68. #ifdef __USE_GNU
  69.         popup->ob_spec=(unsigned long)70128;
  70. #else
  71.         popup->ob_spec=(OBJECT*)70128;
  72. #endif
  73.  
  74.         max_w=1;
  75.         lt=popup; ltb=texts;
  76.         
  77.         for(f=0; f<(n+1); f++)
  78.         {
  79.             a=strlen(t[f]);
  80.             if (a>max_w) { max_w=a; }
  81.         }
  82.  
  83.         if (oxywh.g_w<max_w*8+10) { oxywh.g_w=max_w*8+10; }
  84.         if (oxywh.g_x+oxywh.g_w+5>scrn_x+scrn_w) { oxywh.g_x=scrn_x+scrn_w-oxywh.g_w-5; }
  85.         if (oxywh.g_y+(n+1)*16+24>scrn_y+scrn_h) { oxywh.g_y=scrn_y+scrn_h-((n+1)*16+24); }
  86.     
  87.         for(f=1;f<(n+1);f++)
  88.         {
  89.             lt++;
  90.             lt->ob_next=f+1;
  91.             lt->ob_head=-1;
  92.             lt->ob_tail=-1;
  93.             lt->ob_flags= mask_selectable | mask_exit | mask_rbutton;
  94.             if (f==current)                                    /*Highlight the current selection*/
  95.             {
  96.                 lt->ob_state=mask_selected;
  97.                 lt->ob_flags=mask_selectable | mask_exit | mask_rbutton | mask_default;
  98.             } else {
  99.                 lt->ob_state=0;
  100.             }
  101.             lt->ob_type=G_TEXT;
  102.             lt->ob_x=5;
  103.             lt->ob_y=f*16+10;
  104.             lt->ob_width=oxywh.g_w-10;
  105.             lt->ob_height=16;
  106. #ifdef __USE_GNU
  107.             lt->ob_spec=(unsigned long)ltb;
  108. #else
  109.             lt->ob_spec=(OBJECT*)ltb;
  110. #endif
  111.             ltb->te_ptext=t[f];
  112.             ltb->te_ptmplt=t[f];
  113.             ltb->te_pvalid=t[f];
  114.             ltb->te_font=3;
  115.             ltb->te_just=0;
  116.             ltb->te_color=4464;
  117.             ltb->te_tmplen=ltb->te_txtlen=strlen(t[f])+1;
  118.             ltb++;
  119.         }
  120.  
  121.         lt++;
  122.         lt->ob_type=G_BOX;
  123.         lt->ob_next=0;
  124.         lt->ob_head=n+2;
  125.         lt->ob_tail=n+2;
  126.         lt->ob_flags=0;
  127.         lt->ob_state=0;
  128.         lt->ob_type=G_BOX;
  129.         lt->ob_x=0;
  130.         lt->ob_y=0;
  131.         lt->ob_width=oxywh.g_w;
  132.         lt->ob_height=18;
  133. #ifdef __USE_GNU
  134.         lt->ob_spec=(unsigned long)70129;
  135. #else
  136.         lt->ob_spec=(OBJECT*)70129;
  137. #endif
  138.  
  139.         lt++;
  140.     
  141.         lt->ob_next=n+1;            /*Current Selection Text*/
  142.         lt->ob_head=-1;
  143.         lt->ob_tail=-1;
  144.         lt->ob_flags=LASTOB;
  145.         lt->ob_state=0;
  146.         lt->ob_type=G_TEXT;
  147.         lt->ob_x=5;
  148.         lt->ob_y=1;
  149.         lt->ob_width=oxywh.g_w-10;
  150.         lt->ob_height=16;
  151. #ifdef __USE_GNU
  152.         lt->ob_spec=(unsigned long)ltb;
  153. #else
  154.         lt->ob_spec=(OBJECT*)ltb;
  155. #endif
  156.         ltb->te_ptext=t[0];
  157.         ltb->te_ptmplt=t[0];
  158.         ltb->te_pvalid=t[0];
  159.         ltb->te_font=3;
  160.         ltb->te_just=0;
  161.         ltb->te_color=4208;
  162.         ltb->te_tmplen=ltb->te_txtlen=strlen(t[current])+1;
  163.  
  164.         popup->ob_x=oxywh.g_x;
  165.         popup->ob_y=oxywh.g_y;
  166.         popup->ob_width=oxywh.g_w;
  167.         popup->ob_height=(n+1)*16+18;
  168.  
  169.         buf=(short*)malloc(((scrn_planes*(popup->ob_width+8))/4)*(popup->ob_height+8));
  170.  
  171.         if (buf)
  172.         {
  173.             scr.fd_addr=NULL;
  174.  
  175.             graf_mouse(M_OFF,NULL);
  176.  
  177.             obm.fd_addr=buf;
  178.             obm.fd_w=popup->ob_width+6;
  179.             obm.fd_h=popup->ob_height+6;
  180.             obm.fd_wdwidth=(short)(obm.fd_w/8);
  181.             obm.fd_stand=1;
  182.             obm.fd_nplanes=scrn_planes;
  183.  
  184.             p[0]=popup->ob_x; p[1]=popup->ob_y;
  185.             p[2]=p[0]+popup->ob_width+2; p[3]=p[1]+popup->ob_height+2;
  186.             p[4]=p[5]=1;
  187.             p[6]=p[4]+popup->ob_width+2; p[7]=p[5]+popup->ob_height+2;
  188.             wind_update(BEG_UPDATE);
  189.             vro_cpyfm(x_handle,S_ONLY,p,&scr,&obm);
  190.         }else{
  191.             form_alert(1,"[3][ | DULIB GUI ERROR: | Out of memory for popup menu | background buffering. ][ Cancel ]");
  192.             return current;
  193.         }
  194.     
  195.         objc_draw(popup,0,5,oxywh.g_x,oxywh.g_y,oxywh.g_w+5,(n+1)*16+20);
  196.  
  197.         graf_mouse(M_ON,NULL);
  198.         
  199.         wind_update(BEG_MCTRL);
  200.         
  201.         ex_f=rtn=0; c=current;
  202.         
  203.         graf_mouse(USER_DEF,&SIDEARRW);
  204.         
  205.         while (!ex_f) {
  206.         
  207.         if (sel_f)
  208.         {
  209. #ifndef __USE_GNU
  210.                 e=evnt_multi(MU_KEYBD|MU_BUTTON|MU_M1|MU_TIMER, 1, 1, 1, 1, mx, my, 1, 1,0,0,0,0,0,
  211.                     messB,100,0,&mx,&my,&mb,&dummy,&dummy,&dummy);
  212. #else
  213.                 e=evnt_multi(MU_KEYBD|MU_BUTTON|MU_M1|MU_TIMER, 1, 1, 1, 1,mx,my,1,1,0,0,0,0,0,
  214.                     messB,100,&mx,&my,&mb,&dummy,&dummy,&dummy);
  215. #endif
  216.             }else{
  217. #ifndef __USE_GNU
  218.                 e=evnt_multi(MU_BUTTON|MU_M1, 1, 1, 1, 1, mx, my, 1, 1,0,0,0,0,0,
  219.                     messB,100,0,&mx,&my,&mb,&dummy,&dummy,&dummy);
  220. #else
  221.                 e=evnt_multi(MU_BUTTON|MU_M1, 1, 1, 1, 1,mx,my,1,1,0,0,0,0,0,
  222.                     messB,100,&mx,&my,&mb,&dummy,&dummy,&dummy);
  223. #endif
  224.                 if ((e&MU_BUTTON)==0) graf_mkstate(&mx,&my,&mb,&junk);
  225.             }
  226.             
  227.             rtn=objc_find(popup,0,1,mx,my);
  228.             if ((rtn>n)||(rtn<1)) rtn=current;
  229.             
  230.             if (rtn!=c)
  231.             {
  232.                 if (c)
  233.                     objc_change(popup,c,0,oxywh.g_x,oxywh.g_y,oxywh.g_w+5,(n+1)*16+20, 0, 1);
  234.                 
  235.                 c=rtn;
  236.                 
  237.                 if (c)
  238.                     objc_change(popup,c,0,oxywh.g_x,oxywh.g_y,oxywh.g_w+5,(n+1)*16+20, mask_selected, 1);
  239.             }
  240.             
  241.             if ((sel_f==FALSE)&&(mb==1))
  242.                 ex_f=1;
  243.             
  244.             if ((sel_f==TRUE)&&(mb==0))
  245.                 ex_f=1;
  246.         }
  247.         
  248.         graf_mouse(ARROW,NULL);
  249.         graf_mouse(M_OFF,NULL);
  250.  
  251.         scr.fd_addr=NULL;
  252.         p[0]=p[1]=1;
  253.         p[2]=p[0]+popup->ob_width+2; p[3]=p[1]+popup->ob_height+2;
  254.         p[4]=popup->ob_x; p[5]=popup->ob_y;
  255.         p[6]=p[4]+popup->ob_width+2; p[7]=p[5]+popup->ob_height+2;
  256.         vro_cpyfm(x_handle,S_ONLY,p,&obm,&scr);
  257.  
  258.         graf_mouse(M_ON,NULL);
  259.         free(buf);
  260.         
  261.         wind_update(END_MCTRL);
  262.         
  263.         wind_update(END_UPDATE);
  264.     }
  265.     
  266.     do {
  267.         graf_mkstate(&junk,&junk,&mb,&junk);
  268.     } while (mb!=0);
  269.     
  270.     return rtn;
  271. }
  272.